<template>
  <view class="ai-chat-container">
    <!-- 顶部标题 -->
    <view class="chat-header">
      <text class="header-title">AI智能助手</text>
    </view>

    <!-- 聊天内容区域 -->
    <scroll-view
      scroll-y
      class="chat-history"
      :scroll-into-view="scrollIntoView"
      :scroll-with-animation="true"
    >
      <view
        v-for="(msg, idx) in messages"
        :key="idx"
        :id="'msg-' + idx"
        class="message-container"
      >
        <view
          class="message-bubble"
          :class="msg.role"
        >
          <view class="message-content" v-html="msg.content"></view>
          <view class="message-time">{{ formatTime() }}</view>
        </view>
      </view>
    </scroll-view>

    <!-- 底部输入区域 -->
    <view class="input-area">
      <view class="input-bar">
        <!-- 上传按钮 -->
        <button
          class="upload-btn"
          @click="handleUpload"
        >
          <image
            src="/static/upload-icon.png"
            mode="aspectFit"
            class="upload-icon"
          />
        </button>

        <input
          v-model="userInput"
          class="chat-input"
          placeholder="请输入你的问题..."
          placeholder-class="input-placeholder"
          :disabled="loading"
          @confirm="onSend"
          confirm-type="send"
        />

        <button
          class="send-btn"
          @click="onSend"
          :disabled="loading || !userInput"
          :class="{ disabled: loading || !userInput }"
        >
          <text v-if="!loading">发送</text>
          <view v-else class="loading-icon"></view>
        </button>
      </view>

      <!-- 状态提示 -->
      <view class="status-area">
        <view v-if="loading" class="loading-indicator">
          <view class="loading-dot"></view>
          <text>AI思考中...</text>
        </view>
        <view v-if="errorMsg" class="error-message">
          <text>{{ errorMsg }}</text>
        </view>
      </view>
    </view>
  </view>
</template>

<script setup lang="ts">
import { ref, nextTick } from 'vue';
import { onLoad, onShow, onReachBottom } from "@dcloudio/uni-app"
import { get } from 'http';
import { saveMessageToRedis } from '../../apis/AIChatAPI';

interface Message {
  role: 'user' | 'ai';
  content: string;
}

const userInput = ref('');
const messages = ref<Message[]>([]);
const loading = ref(false);
const errorMsg = ref('');
const scrollIntoView = ref('');
const sessionId = ref('')
const messageId = ref('')
const request = ref({
  sessionId:'',
  messageId:'',
  userId:uni.getStorageSync('userInfo').userId,
  userInput:'',
  aiResponse:''
})
const timestamp = ref("")
const randomStr = ref('')
const filePath = ref('')

// 发送消息
const onSend = async () => {
  if (!userInput.value.trim() || loading.value) return;

  let input = userInput.value.trim();
  const hasImage = !!filePath.value; // 判断是否有图片路径

  // 拼接规则：文字 + 图片路径（根据需求自定义格式，此处用换行分隔）
    if (hasImage) {
      input =  `${input}\n[图片filePath]${filePath.value}`
    }

  messages.value.push({ role: 'user', content: input });

  userInput.value = '';
  filePath.value = ''; // 发送后清空图片路径，避免重复发送
  loading.value = true;
  errorMsg.value = '';

  await nextTick();
  scrollToBottom();

  // 添加AI消息占位
  const aiMsg: Message = { role: 'ai', content: '' };
  messages.value.push(aiMsg);
  await nextTick();
  scrollToBottom();

  // 流式请求
  await streamAIResponse(input, aiMsg);
};

// 流式获取AI回复（SSE兼容小程序方案：递归轮询）
function streamAIResponse(input: string, aiMsg: Message) {
  let finished = false;
  let lastLength = 0;
  request.value.userInput = input
  console.log("request",request)
  request.value.sessionId = sessionId.value
  // 递归轮询
  const poll = async () => {
    if (finished) return;
    try {
      await new Promise<void>((resolve, reject) => {
        uni.request({
          url: 'http://localhost:1010/ai/chat/stream',
          method: 'POST',
          data: request.value,
          header: { Accept: 'text/event-stream' },
          timeout: 60000,
          success: (res) => {
            // 处理流式 data:xxx\n
            const raw = res.data as string;
            // 只处理新内容
            const lines = raw.split(/\r?\n/).filter(l => l.startsWith('data:'));
            let newText = '';
            for (let i = lastLength; i < lines.length; i++) {
              const line = lines[i];
              const chunk = line.replace(/^data:/, '').trim();
              if (chunk === '[END]') {
                finished = true;
                break;
              }
              newText += chunk;
            }
            if (newText) {
              aiMsg.content += newText;
              lastLength = lines.length;
              nextTick(scrollToBottom);
            }
            // 判断是否结束
            if (finished || !newText) {
              finished = true;
              loading.value = false;
              saveChatRecord(input, aiMsg.content);
              resolve();
            } else {
              setTimeout(poll, 600);
              resolve();
            }
          },
          fail: () => {
            errorMsg.value = 'AI请求失败';
            loading.value = false;
            finished = true;
            resolve();
          }
        });
      });
    } catch {
      loading.value = false;
      finished = true;
    }
  };
  poll();
}

// 保存对话
function saveChatRecord(user: string, ai: string) {
  createId()
  messageId.value = "mini"+timestamp.value+randomStr.value
  console.log("MsgId",messageId.value)
  console.log("sessionId",sessionId.value)
  request.value.messageId = messageId.value
  // 存用户
  request.value.userInput = user
  request.value.aiResponse = ai
  saveMessageToRedis(request.value)
}

// 上传文件处理
// 上传文件处理
const handleUpload = () => {
  uni.chooseImage({
    count: 1,
    sizeType: ['compressed'],
    sourceType: ['album', 'camera'],
    success: (res) => {
      const tempFilePaths = res.tempFilePaths;
      if (!tempFilePaths.length) {
        errorMsg.value = '未选择文件';
        return;
      }

      // 1. 获取本地存储的认证信息（如果后端需要）
      const token = uni.getStorageSync('token') || '';
      const userId = uni.getStorageSync('userInfo')?.userId || '';

      uni.uploadFile({
        // 2. 确认后端上传接口的正确地址（重点检查端口和路径）
        url: 'http://localhost:10000/oss/upload', // 请确认此地址是否正确
        filePath: tempFilePaths[0],
        name: 'file', // 与后端接收文件的参数名保持一致
        success: (uploadRes) => {
          // 解析响应（后端可能返回JSON字符串）
          try {
			  console.log("sadada",uploadRes.data)
            const result = JSON.parse(uploadRes.data);
            if (result.code === 200) {
                const imageUrl = result.data.url;// 假设后端返回图片URL
				filePath.value = result.data.url;
                messages.value.push({
                  role: 'user',
                  content: `<img src="${imageUrl}" style="max-width: 100%; border-radius: 8rpx;" />`
                });
                nextTick(scrollToBottom);
            } else {
              errorMsg.value = `服务器错误: ${result.msg || uploadRes.statusCode}`;
            }
          } catch (e) {
            errorMsg.value = '解析响应失败，请检查后端格式';
          }
        },
        fail: (err) => {
          // 5. 打印详细错误信息（关键排查依据）
          console.error('上传失败详情:', err);
          errorMsg.value = `上传失败: ${err.errMsg || '未知错误'}`;
        },
        complete: () => {
          // 可添加上传完成的通用逻辑
        }
      });
    },
    fail: (err) => {
      console.error('选择图片失败:', err);
      errorMsg.value = `选择图片失败: ${err.errMsg}`;
    }
  });
};
function scrollToBottom() {
  scrollIntoView.value = 'msg-' + (messages.value.length - 1);
}

// 简单时间格式化
const formatTime = () => {
  const now = new Date();
  const hours = now.getHours().toString().padStart(2, '0');
  const minutes = now.getMinutes().toString().padStart(2, '0');
  return `${hours}:${minutes}`;
}

const createId = () => {
  timestamp.value = Date.now().toString(36);
  randomStr.value = Math.random().toString(36).substr(2, 9);
}

onLoad(()=>{
  createId()
  sessionId.value = "mini"+timestamp.value+randomStr.value
  console.log(sessionId.value)
})
</script>

<style lang="scss">
/* 颜色变量 */
$primary-color: #1e88e5;
$user-bubble: #1e88e5;
$ai-bubble: #ffffff;
$border-color: #eaeaea;
$text-color: #333333;
$text-light: #999999;
$error-color: #ff4d4f;

.ai-chat-container {
  display: flex;
  flex-direction: column;
  height: 100vh;
  background-color: #f5f7fa;
  padding: 0;
}

/* 头部样式 */
.chat-header {
  padding: 20rpx 30rpx;
  background-color: white;
  border-bottom: 1rpx solid $border-color;

  .header-title {
    font-size: 36rpx;
    font-weight: bold;
    color: $text-color;
  }
}

/* 聊天历史区域 */
.chat-history {
  flex: 1;
  padding: 20rpx;
  overflow-y: auto;
}

.message-container {
  margin-bottom: 30rpx;
}

.message-bubble {
  max-width: 80%;
  border-radius: 16rpx;
  padding: 16rpx 24rpx;
  position: relative;
  word-break: break-word;
  box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.08);

  &.user {
    background-color: $user-bubble;
    color: white;
    margin-left: auto;
    border-bottom-right-radius: 4rpx;

    .message-time {
      color: rgba(255, 255, 255, 0.7);
    }
  }

  &.ai {
    background-color: $ai-bubble;
    color: $text-color;
    margin-right: auto;
    border: 1rpx solid $border-color;
    border-bottom-left-radius: 4rpx;
  }

  .message-content {
    font-size: 28rpx;
    line-height: 1.5;
  }

  .message-time {
    font-size: 22rpx;
    margin-top: 8rpx;
    text-align: right;
    color: $text-light;
  }
}

/* 输入区域 */
.input-area {
  padding: 20rpx;
  background-color: white;
  border-top: 1rpx solid $border-color;
}

.input-bar {
  display: flex;
  align-items: center;
  position: relative;
}

.upload-btn {
  width: 80rpx;
  height: 80rpx;
  padding: 0;
  margin-right: 16rpx;
  background-color: transparent;
  border: none;
  display: flex;
  align-items: center;
  justify-content: center;

  .upload-icon {
    width: 48rpx;
    height: 48rpx;
  }
}

.chat-input {
  flex: 1;
  height: 80rpx;
  padding: 0 24rpx;
  background-color: #f5f5f5;
  border-radius: 40rpx;
  font-size: 28rpx;
  color: $text-color;
  border: none;

  .input-placeholder {
    color: $text-light;
  }
}

.send-btn {
  width: 120rpx;
  height: 80rpx;
  margin-left: 16rpx;
  background-color: $primary-color;
  color: white;
  border-radius: 40rpx;
  font-size: 28rpx;
  padding: 0;
  border: none;
  display: flex;
  align-items: center;
  justify-content: center;

  &.disabled {
    background-color: #cccccc;
    opacity: 0.7;
  }

  .loading-icon {
    width: 32rpx;
    height: 32rpx;
    border: 4rpx solid rgba(255, 255, 255, 0.3);
    border-radius: 50%;
    border-top-color: white;
    animation: spin 1s linear infinite;
  }
}

/* 状态区域 */
.status-area {
  margin-top: 16rpx;
  min-height: 40rpx;
  text-align: center;

  .loading-indicator {
    display: flex;
    align-items: center;
    justify-content: center;
    color: $text-light;
    font-size: 24rpx;

    .loading-dot {
      width: 16rpx;
      height: 16rpx;
      background-color: $text-light;
      border-radius: 50%;
      margin-right: 8rpx;
      animation: pulse 1.5s infinite ease-in-out;
    }
  }

  .error-message {
    color: $error-color;
    font-size: 24rpx;
  }
}

/* 动画 */
@keyframes spin {
  to { transform: rotate(360deg); }
}

@keyframes pulse {
  0%, 100% { opacity: 0.5; transform: scale(0.8); }
  50% { opacity: 1; transform: scale(1); }
}
</style>